﻿/************
* 摘要:工位机扫码装箱界面 MVVM
* 软件名称: 雪克码 工位机 系统
* 文件名: PackBoxViewModel.cs
* 版本: 1.0
*/
using AutoMapper;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.Mvvm.Messaging.Messages;
using HandyControl.Data;
using Microsoft.Extensions.Logging;
using ShanNiang.Hosting;
using ShanNiang.Hosting.Enumerate;
using ShanNiang.Mvvm.SaveModels;
using ShanNiang.Mvvm.UiServices;
using ShanNiang.Service;
using ShanNiang.Service.Attributes;
using ShanNiang.Service.Constants;
using ShanNiang.Service.Enumerate;
using ShanNiang.Service.Interfaces;
using ShanNiang.Service.PackingModels.Requests;
using ShanNiang.Service.Scaner;
using System.Collections.ObjectModel;

namespace ShanNiang.Mvvm.ViewModels
{
    //[ViewModelFile("pack_box.json", typeof(PackBoxModel))]
    public partial class PackBoxViewModel : ScannableViewModel //, IRecipient<PropertyChangedMessage<string?>>
    {
        #region 服务入驻
        private readonly IXkmService _xkmService;
        private readonly ISoundService _soundService;
        private readonly UserContext _userContext;

        #endregion

        public PackBoxViewModel(
            IUiService uiService,
            IXkmService xkmService,
            ISoundService soundService,
            UserContext userContext,
            PackingConfig packingConfig, IScanerService scanerService, IMapper mapper, ILogger<PackBoxViewModel> logger) : base(packingConfig, scanerService, uiService, mapper, logger)
        {
            _xkmService = xkmService;
            _soundService = soundService;
            _userContext = userContext;

            PageIndex = 1;
            AutoPacking = true;
            Items = new ObservableCollection<ItemViewModel>();
            BoxCode = new BoxViewModel(0);
            LoadData();
        }

        #region 字段和可观察属性
        /// <summary>
        /// 自动封箱
        /// </summary>
        [ObservableProperty]
        private bool _autoPacking;
        /// <summary>
        /// 已扫的箱码
        /// </summary>
        [ObservableProperty]
        private BoxViewModel _boxCode;
        /// <summary>
        /// 可选商品
        /// </summary>
        [ObservableProperty]
        private ObservableCollection<ItemViewModel> _items;
        /// <summary>
        /// 当前页码
        /// </summary>
        [ObservableProperty]
        private int _pageIndex;
        /// <summary>
        /// 扫码删除
        /// </summary>
        [ObservableProperty]
        private bool _scanToDelete;
        /// <summary>
        /// 已选择的商品
        /// </summary>
        [ObservableProperty]
        private ItemViewModel? _selectedItem;
        /// <summary>
        /// 展示选择框，
        /// </summary>
        [ObservableProperty]
        private bool _showItems;
        /// <summary>
        /// 商品总页数
        /// </summary>
        [ObservableProperty]
        private int _totalPages;
        /// <summary>
        /// 当前企业
        /// </summary>
        private Guid? CurrentEnterpriseId
        {
            get
            {
                if (_userContext.UserResponse != null)
                {
                    return _userContext.UserResponse.EnterpriseId;
                }
                return null;
            }
        }
        /// <summary>
        /// 页面大小
        /// </summary>
        public int PageSize => CommonData.DEFAULT_PAGE_SIZE;
        #endregion

        #region 可绑定 Command
        /// <summary>
        /// 添加 瓶码
        /// </summary>
        /// <param name="bottleCode"></param>
        [RelayCommand]
        private void AddBottle(string? bottleCode)
        {
            if (string.IsNullOrWhiteSpace(bottleCode))
            {
                bottleCode = Convert.ToBase64String(BitConverter.GetBytes(new Random().NextInt64()));
            }
            if (!BoxCode.BottleCodes.Any(p => p.BottleCode == bottleCode))
            {
                var current = BoxCode.BottleCodes.FirstOrDefault(p => !p.Valid);
                if (current != null)
                {
                    current.BottleCode = bottleCode;
                    BoxCode.NotifyPackedCountToChange();
                }
                else
                {
                    UiService.GrowlInfo("瓶码已扫满", CodeType.BottleCode);
                }
            }
            else
            {
                UiService.GrowlWarning($"瓶码{bottleCode}已添加过", CodeType.BottleCode);
            }

        }
        /// <summary>
        /// 拆箱
        /// </summary>
        /// <returns></returns>
        [RelayCommand]
        private async Task BreakBoxCodeAsync()
        {
            if (string.IsNullOrEmpty(BoxCode.BoxCode))
            {
                UiService.GrowlWarning("空码不能拆箱", CodeType.BoxCode);
                return;
            }
            if (!BoxCode.Modification)
            {
                UiService.GrowlWarning("新码不能拆箱", CodeType.BoxCode);
                return;
            }

            var request = new UnpackBoxesRequest(CurrentEnterpriseId, BoxCode.BoxCode);
            try
            {
                var response = await _xkmService.UnpackBoxesAsync(request);
                ClearBoxCode();
                UiService.GrowlSuccess("拆箱成功", CodeType.BoxCode);
            }
            catch (ApiException ex)
            {
                UiService.GrowlWarning(ex.Message, CodeType.BoxCode, ex);
            }
            catch (Exception ex)
            {
                UiService.GrowlError(ex.Message, CodeType.BoxCode, ex);
            }

        }
        /// <summary>
        /// 删除瓶码
        /// </summary>
        /// <param name="bottleCode"></param>
        [RelayCommand]
        private void DeleteBottle(object? bottleCode)
        {
            if (bottleCode != null)
            {
                var bottleViewModel = (BottleCodeViewModel)bottleCode;
                bottleViewModel.BottleCode = null;
                BoxCode.NotifyPackedCountToChange();
            }
        }
        ///// <summary>
        ///// 切换到装箱记录
        ///// </summary>
        //[RelayCommand]
        //private void ChangeToPackingRecoder()
        //{
        //    _mainFormViewModel.SelectedMenu = _mainFormViewModel.User.MenuCodes.Where(p => p.MenuCode == CommonData.MENU_HISTORY).SingleOrDefault();
        //}
        /// <summary>
        /// 清除箱码
        /// </summary>
        [RelayCommand]
        private void ClearBoxCode()
        {
            BoxCode.BoxCode = null;
            BoxCode.Modification = false;
            foreach (var bottleCode in BoxCode.BottleCodes)
            {
                bottleCode.BottleCode = "";
            }
        }
        /// <summary>
        /// 清空选择
        /// </summary>
        [RelayCommand]
        private void ClearSelected()
        {
            SelectedItem = null;
        }
        /// <summary>
        /// 刷新商品
        /// </summary>
        /// <returns></returns>
        [RelayCommand]
        private async Task LoadItemsAsync(FunctionEventArgs<int> parameter)
        {

            GetItemsPageRequest getItemsRequest = new GetItemsPageRequest();

            if (parameter != null)
            {
                PageIndex = parameter.Info;
            }
            getItemsRequest.PageIndex = PageIndex;
            getItemsRequest.PageSize = CommonData.DEFAULT_PAGE_SIZE;
            var response = await _xkmService.GetItemsPageAsync(getItemsRequest);
            if (response != null)
            {
                Items = new ObservableCollection<ItemViewModel>(Mapper.Map<List<ItemViewModel>>(response.List));
                ShowItems = true;
                TotalPages = (response.TotalCount - 1) / getItemsRequest.PageSize + 1;
            }
        }
        /// <summary>
        /// 保存箱数据
        /// </summary>
        /// <returns></returns>
        [RelayCommand]
        private async Task SaveBoxAsync()
        {
            var request = GetPackUpBoxRequest();
            if (request != null)
            {
                try
                {
                    var todayPacking = await _xkmService.PackUpBoxAsync(request);
                    UiService.GrowlSuccess("封箱成功", CodeType.BoxCode);
                    if (SelectedItem != null)
                    {
                        SelectedItem.TodayPacking = todayPacking;
                        BoxCode = new BoxViewModel(SelectedItem.BoxSize);
                    }
                }
                catch (ApiException ex)
                {
                    UiService.GrowlWarning(ex.Message, CodeType.BoxCode, ex);
                }
                catch (Exception ex)
                {
                    UiService.GrowlError(ex.Message, CodeType.BoxCode, ex);
                }
            }

        }
        #endregion

        #region 重写、接口实现和事件处理

        /// <summary>
        /// 页面加载
        /// </summary>
        /// <returns></returns>
        protected override async Task LoadedAsync()
        {
            await base.LoadedAsync();
            if (SelectedItem == null)
            {
                if (!string.IsNullOrEmpty(PackingConfig.DefaultBarcode))
                {
                    await ScanBarcodeAsync(PackingConfig.DefaultBarcode);
                }
            }
            if (TotalPages == 0)
            {
                await LoadItemsAsync(new FunctionEventArgs<int>(1));
            }
        }
        partial void OnSelectedItemChanged(ItemViewModel? oldValue, ItemViewModel? newValue)
        {
            if (newValue != null)
            {
                if (oldValue == null || oldValue.Id != newValue.Id)
                {
                    var boxSize = 0;
                    if (SelectedItem != null && SelectedItem.BoxSize > 0)
                    {
                        boxSize = SelectedItem.BoxSize;
                    }
                    BoxCode.BottleCodes.Clear();
                    for (int i = 0; i < boxSize; i++)
                    {
                        BoxCode.BottleCodes.Add(new BottleCodeViewModel());
                    }
                    BoxCode.BoxCode = null;
                    BoxCode.Modification = false;
                }
            }
            else 
            {
                BoxCode.BoxCode = null;
                BoxCode.Modification = false;
                BoxCode.BottleCodes.Clear();
            }
        }
        
        //public async void Receive(PropertyChangedMessage<string?> message)
        //{
        //    if (message != null && message.PropertyName == CommonData.QueryBox && !string.IsNullOrEmpty( message.NewValue))
        //    {
        //        if (message.OldValue == null)
        //        {
        //            ClearBoxCode();
        //            SelectedItem = null;
        //        }
        //        await ScanBoxcodeAsync(message.NewValue);
        //    }
        //}

        protected override async Task CodeScanedAsync(object? sender, CodeEventArgs e)
        {
            if (e.CodeType == CodeType.BottleCode)
            {
                await ScanBottlecodeAsync(e.Code);
            }
            else if (e.CodeType == CodeType.BoxCode)
            {
                await ScanBoxcodeAsync(e.Code);
            }
            else if (e.CodeType == CodeType.Barcode)
            {
                await ScanBarcodeAsync(e.Code);
            }
            else
            {
                _soundService.PlayWanning(CodeType.Unknown);
            }
        }

        #endregion

        #region 其他方法
        /// <summary>
        /// 扫描条码
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        private async Task ScanBarcodeAsync(string code)
        {
            //SystemSounds.Exclamation.Play();
            if (SelectedItem == null)
            {
                var request = new GetItemRequest(code, CurrentEnterpriseId);
                try
                {
                    var item = await _xkmService.GetItemAsync(request);
                    if (item != null)
                    {
                        SelectedItem = Mapper.Map<ItemViewModel>(item);
                        //await CheckAutoPackage();
                        _soundService.PlayInfo(CodeType.Barcode);
                    }
                }
                catch (ApiException ex)
                {
                    if (ex.ErrorCode == GlobalErrorCode.NotFound)
                    {
                        UiService.GrowlWarning("本商品不存在", CodeType.Barcode);
                    }
                    else
                    {
                        UiService.GrowlWarning(ex.Message, CodeType.Barcode, ex);
                    }
                }
                catch (Exception ex)
                {
                    UiService.GrowlError(ex.Message, CodeType.Barcode, ex);
                }
            }
            else
            {
                UiService.GrowlWarning("商品已设置，请删除后重新选择", CodeType.Barcode);
            }
        }
        /// <summary>
        /// 扫描瓶码
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        private async Task ScanBottlecodeAsync(string code)
        {
            if (ScanToDelete)
            {
                var bottleCodeView = BoxCode.BottleCodes.FirstOrDefault(x => x.BottleCode == code);
                if (bottleCodeView != null)
                {
                    DeleteBottle(bottleCodeView);
                    _soundService.PlayInfo(CodeType.BottleCode);
                }
                else
                {
                    UiService.GrowlWarning($"瓶码{code}不在列表里，无法删除", CodeType.BottleCode);
                }
            }
            else
            {
                if (BoxCode.Valid)
                {
                    AddBottle(code);
                    _soundService.PlayInfo(CodeType.BottleCode);
                    await CheckAutoPackage();
                }
                else
                {
                    UiService.GrowlWarning($"请先扫箱码", CodeType.BottleCode);
                }
            }

        }
        /// <summary>
        /// 扫描箱码
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        private async Task ScanBoxcodeAsync(string code)
        {
            //SystemSounds.Beep.Play();
            if (ScanToDelete)
            {
                if (!string.IsNullOrEmpty(BoxCode.BoxCode))
                {
                    if (code == BoxCode.BoxCode)
                    {
                        ClearBoxCode();
                        _soundService.PlayInfo(CodeType.BoxCode);
                    }
                    else
                    {
                        UiService.GrowlWarning($"箱码{code}无效，无法删除", CodeType.BoxCode);
                        return;
                    }
                }
            }
            else
            {
                bool empty = string.IsNullOrEmpty(BoxCode.BoxCode);
                if (!empty)
                {
                    if (code == BoxCode.BoxCode)
                    {
                        UiService.GrowlInfo("箱码已扫描", CodeType.BoxCode);
                        return;
                    }
                    else
                    {
                        UiService.GrowlWarning("箱码已扫描,若您要更换请先删除就箱码", CodeType.BoxCode);
                        return;
                    }
                }
                else
                {
                    try
                    {
                        var getBoxCode = new GetBoxCodeRequest(code, CurrentEnterpriseId);
                        var boxCodeResponse = await _xkmService.GetBoxCodeAsync(getBoxCode);
                        if (boxCodeResponse != null)
                        {
                            if (SelectedItem == null && boxCodeResponse.Item != null)
                            {
                                SelectedItem = Mapper.Map(boxCodeResponse.Item, SelectedItem);
                            }
                            else if (SelectedItem != null && boxCodeResponse.Item != null)
                            {
                                if (SelectedItem.Id != boxCodeResponse.Item.Id)
                                {
                                    UiService.GrowlWarning("已装箱码装箱商品和当前商品不符，不能使用", CodeType.BoxCode);
                                    return;
                                }
                            }
                            else if (SelectedItem == null && boxCodeResponse.Item == null)
                            {
                                UiService.GrowlWarning("装新箱，需要先确定商品", CodeType.BoxCode);
                                return;
                            }
                            BoxCode.BoxCode = code;
                            BoxCode.Modification = boxCodeResponse.Item != null;
                            if (boxCodeResponse.BottleCodes != null && boxCodeResponse.BottleCodes.Count > 0)
                            {
                                foreach (var rspCode in boxCodeResponse.BottleCodes)
                                {
                                    AddBottle(rspCode);
                                }
                            }
                            _soundService.PlayInfo(CodeType.BoxCode);
                        }
                    }
                    catch (ApiException ex)
                    {
                        UiService.GrowlWarning(ex.Message, CodeType.BoxCode, ex);
                    }
                    catch (Exception ex)
                    {
                        UiService.GrowlError(ex.Message, CodeType.BoxCode, ex);
                    }
                    //await CheckAutoPackage();
                }
            }

        }
        /// <summary>
        /// 检测是否自动提交
        /// </summary>
        /// <returns></returns>
        private async Task CheckAutoPackage()
        {
            if (AutoPacking)
            {
                if (!CurrentEnterpriseId.HasValue)
                {
                    return;
                }
                if (SelectedItem == null)
                {
                    return;
                }
                if (string.IsNullOrEmpty(BoxCode.BoxCode))
                {
                    return;
                }
                if (BoxCode.BottleCodes.Where(p => !string.IsNullOrEmpty(p.BottleCode)).Count() != SelectedItem.BoxSize)
                {
                    return;
                }
                await SaveBoxAsync();
            }
        }
        /// <summary>
        /// 获取自动提交请求
        /// </summary>
        /// <returns></returns>
        private PackUpBoxRequest? GetPackUpBoxRequest()
        {

            if (!CurrentEnterpriseId.HasValue)
            {
                UiService.GrowlError("请重新登陆", CodeType.Unknown);
                return null;
            }
            if (SelectedItem == null)
            {
                UiService.GrowlWarning("请选择商品", CodeType.Barcode);
                return null;
            }
            if (string.IsNullOrEmpty(BoxCode.BoxCode))
            {
                UiService.GrowlWarning("请选箱码", CodeType.BoxCode);
                return null;
            }
            var bottleCodes = BoxCode.BottleCodes.Where(p => !string.IsNullOrEmpty(p.BottleCode)).Select(p => p.BottleCode).ToArray();
            if (bottleCodes == null || bottleCodes.Length == 0) //|| bottleCodes.Length != SelectedItem.BoxSize)
            {
                UiService.GrowlWarning("无瓶码不能装箱", CodeType.BoxCode);
                return null;
            }
            if (bottleCodes.Length != SelectedItem.BoxSize)
            {
                UiService.GrowlWarning("瓶数和箱规不符", CodeType.BoxCode);
            }
            return new PackUpBoxRequest(BoxCode.BoxCode, SelectedItem.Id, bottleCodes, _userContext.UserResponse?.EnterpriseId);
        }
        #endregion

    }
}
